﻿using FNN.CustomFunctions;
using FNN.Helpers;
using FNN.NetworkMasters;
using FNN.Networks;
using FNN.SourcePoints;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Configuration;

namespace GraphicFNN.Pages
{
    /// <summary>
    /// Логика взаимодействия для CultivationPage.xaml
    /// </summary>
    public partial class CultivationPage : Page
    {
        public CultivationPage()
        {
            InitializeComponent();
        }

        protected List<DateSourcePoint> GetFinancialDataSource(string pathToData)
        {
            var csvHelper = new FinancialCsvHelper(pathToData);
            var initialData = csvHelper.GetBody();
            var dataHeaders = csvHelper.GetHeader();
            var tempList = csvHelper.ProcessData(dataHeaders, initialData);
            List<DateSourcePoint> result = new List<DateSourcePoint>();

            foreach (var point in tempList)
            {
                result.Add((DateSourcePoint)point);
            }

            return result;
        }

        protected List<SourcePoint> GetDataSource(string pathToData)
        {
            CsvHelper csvHelper = null;

            switch ((NetworkMastersList)CmbType.SelectedIndex)
            {
                case NetworkMastersList.Financial:
                    csvHelper = new FinancialCsvHelper(pathToData);
                    break;
                case NetworkMastersList.Regular:
                    csvHelper = new RegularCsvHelper(pathToData);
                    break;
            }

            if (csvHelper == null) return null;
            var initialData = csvHelper.GetBody();
            var dataHeaders = csvHelper.GetHeader();
            var result = csvHelper.ProcessData(dataHeaders, initialData);

            return result;
        }

        private void BtnCultivate_OnClick(object sender, RoutedEventArgs e)
        {
            NetworkMaster netMaster = null;
            Network targetNetwork = null;
            var chartWindow = new ChartWindow();
            var defaultPopulationCount = Convert.ToInt32(ConfigurationManager.AppSettings["defaultPopulationCount"]);

            switch ((NetworkMastersList)CmbType.SelectedIndex)
            {
                case NetworkMastersList.Financial:
                    netMaster = new FinancialNetworkMaster { PopulationCount = defaultPopulationCount };
                    ((FinancialNetworkMaster)netMaster).GenerationResultsImproved += chartWindow.CatchResultsImproved;
                    ((FinancialNetworkMaster)netMaster).GenerationChanged += chartWindow.CatchIterationChanged;
                    ((FinancialNetworkMaster)netMaster).DataSource = GetDataSource(TxtSourcePath.Text);
                    targetNetwork = new FinancialNetwork(Convert.ToInt32(TxtInputCount.Text), Convert.ToInt32(TxtLayerCount.Text),
                            Convert.ToInt32(TxtLayerNeuronCount.Text),
                            new List<FunctionTypes> { (FunctionTypes)(CmbFunctions.SelectedIndex - 1) },
                            Convert.ToInt32(TxtOutputCount.Text));
                    break;
                case NetworkMastersList.Regular:
                    netMaster = new RegularNetworkMaster { PopulationCount = defaultPopulationCount };
                    ((RegularNetworkMaster)netMaster).GenerationResultsImproved += chartWindow.CatchResultsImproved;
                    ((RegularNetworkMaster)netMaster).GenerationChanged += chartWindow.CatchIterationChanged;
                    ((RegularNetworkMaster)netMaster).DataSource = GetDataSource(TxtSourcePath.Text);
                    targetNetwork = new RegularNetwork(Convert.ToInt32(TxtInputCount.Text), Convert.ToInt32(TxtLayerCount.Text),
                            Convert.ToInt32(TxtLayerNeuronCount.Text),
                            new List<FunctionTypes> { (FunctionTypes)(CmbFunctions.SelectedIndex - 1) },
                            Convert.ToInt32(TxtOutputCount.Text));
                    break;
            }

            if (netMaster == null) return;
            netMaster.IterationsLimit = 1000;
            netMaster.GeneticIterationsLimit = 1000;
            chartWindow.Show();
            var backgroundTask = Task.Factory.StartNew(() =>
            {
                var serializationHelper = new SerializationHelper();
                var targetName = "";
                Dispatcher.Invoke(() =>
                {
                    targetName = TxtNetworkName.Text;
                    var resultNetwork = netMaster.NetworkCultivation(targetNetwork, true);
                    serializationHelper.WriteBinary(resultNetwork, targetName + ".fnn");
                });
            });
        }

        private void BtnSelectSource_OnClick(object sender, RoutedEventArgs e)
        {
            var fileBrowser = new OpenFileDialog
            {
                CheckFileExists = true,
                Multiselect = false,
                Filter = "CSV|*.csv"
            };
            fileBrowser.ShowDialog();
            TxtSourcePath.Text = fileBrowser.FileName;
        }
    }
}
